package com.uyayo.system.authority.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.uyayo.framework.common.exception.CodeMultipleException;
import com.uyayo.framework.common.exception.ParentNotFoundException;
import com.uyayo.system.authority.entity.SysResource;
import com.uyayo.system.authority.entity.SysOrganizationResource;
import com.uyayo.system.authority.mapper.SysOrganizationMapper;
import com.uyayo.system.authority.service.SysOrganizationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.uyayo.framework.message.model.Result;
import com.uyayo.framework.common.util.CodeUtil;
import com.uyayo.system.authority.entity.SysOrganization;
import com.uyayo.system.authority.mapper.SysOrganizationResourceMapper;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;




@Service("sysOrganizationService")
public class SysOrganizationServiceImpl implements SysOrganizationService {
	
	private final SysOrganizationMapper organizationMapper;
	
	private final SysOrganizationResourceMapper organizationResourceMapper;

    private final SysOrganizationResourceMapper sysOrganizationResourceMapper;

    @Autowired
    public SysOrganizationServiceImpl(SysOrganizationResourceMapper sysOrganizationResourceMapper, SysOrganizationMapper organizationMapper, SysOrganizationResourceMapper organizationResourceMapper) {
        this.sysOrganizationResourceMapper = sysOrganizationResourceMapper;
        this.organizationMapper = organizationMapper;
        this.organizationResourceMapper = organizationResourceMapper;
    }


    @Override
	public List<SysOrganization> organizationTreeGrid(SysOrganization organization) {
		List<SysOrganization> organizations;
		Example example = new Example(SysOrganization.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo(organization);
		organizations = organizationMapper.selectByExample(example);
		return organizations;
	}

	@Override
	public List<SysOrganization> selectOrganizationAll(SysOrganization organization) {
		List<SysOrganization> organizations = new ArrayList<>();
		try {
			Example example = new Example(SysOrganization.class);  
			organizations = organizationMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return organizations;
	}

	@Override
	public SysOrganization selectOrganizationById(String organizationId) {
		SysOrganization organization = new SysOrganization();
		try {
			organization = organizationMapper.selectByPrimaryKey(organizationId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return organization;
	}

	@Override
	public int selectCountByParentId(String parentId) {
		SysOrganization sysOrganization = new SysOrganization();
		sysOrganization.setParentId(parentId);
		return organizationMapper.selectCount(sysOrganization);
	}

	@Override
	public int saveOrganization(SysOrganization organization) throws CodeMultipleException, ParentNotFoundException {
		String parentId = organization.getParentId();
		SysOrganization sysOrganizationCondition = new SysOrganization();
		sysOrganizationCondition.setCode(organization.getCode());
		SysOrganization sysOrganizationTest = organizationMapper.selectOne(sysOrganizationCondition);
		if(sysOrganizationTest!=null){
			throw new CodeMultipleException("Code multiple error!");
		}
		if(StringUtils.isNotEmpty(parentId)){
			SysOrganization sysOrganizationParent = selectOrganizationById(parentId);
			if(sysOrganizationParent==null){
				throw new ParentNotFoundException("Parent not found!");
			}
		}

		int count = organizationMapper.insertSelective(organization);
		if(count >0){
			updateHasChildrennToParent( parentId);
		}
		return count;
		
	}

	/**
	 * 修改父机构是否含子机构
	 * @param parentId 父机构id
	 */
	private void  updateHasChildrennToParent(String parentId){
		if(StringUtils.isNotEmpty(parentId)){
			SysOrganization sysOrganization = new SysOrganization();
			sysOrganization.setId(parentId);
			if(selectCountByParentId(parentId)>0) {
				sysOrganization.setHasChildren(true);
			}else{
				sysOrganization.setHasChildren(false);
			}
			organizationMapper.updateByPrimaryKeySelective(sysOrganization);
		}
	}

	/**
	 * 迭代检查选择的上级id是否是自己的子级
	 * @param parentIdOld 原上级id
	 * @param parentIdNew	新上级id
	 * @param sysOrganizationChild 子机构
	 * @param sysOrganizationParent 父机构
	 */
    private void recursiveCheckParentIsChildren(String parentIdOld, String parentIdNew, SysOrganization sysOrganizationChild, SysOrganization sysOrganizationParent){
		if (selectCountByParentId(sysOrganizationChild.getId()) > 0) {
			Example example = new Example(SysResource.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andEqualTo("parentId",sysOrganizationChild.getId());
			List<SysOrganization> sysOrganizations = organizationMapper.selectByExample(example);
			if (!sysOrganizations.isEmpty()) {
				for(SysOrganization sysOrganization:sysOrganizations){
					if(StringUtils.equals(sysOrganization.getId(),parentIdNew)){
						sysOrganizationParent.setParentId(parentIdOld);
						organizationMapper.updateByPrimaryKeySelective(sysOrganizationParent);
					}else {
						recursiveCheckParentIsChildren(parentIdOld, parentIdNew, sysOrganization, sysOrganizationParent);
					}
				}
			}
		}
	}

	
	@Override
	public int updateOrganization(SysOrganization organization) throws CodeMultipleException, ParentNotFoundException {
		SysOrganization sysResourceCondition = new SysOrganization();
		sysResourceCondition.setCode(organization.getCode());
		SysOrganization sysResourceTest = organizationMapper.selectOne(sysResourceCondition);
		if(sysResourceTest!=null && !StringUtils.equals(organization.getId(),sysResourceTest.getId())){
			throw new CodeMultipleException("Code multiple error!");
		}

		SysOrganization sysOrganizationOld = selectOrganizationById(organization.getId());

		String parentId = organization.getParentId();
		if(StringUtils.isNotEmpty(parentId)){

			//获取修改的父级资源
			SysOrganization sysOrganizationParent = selectOrganizationById(parentId);
			if(sysOrganizationParent==null){
				throw new ParentNotFoundException("Parent not found!");
			}
			if (selectCountByParentId(sysOrganizationOld.getId()) > 0) {
				Example example = new Example(SysResource.class);
				Example.Criteria criteria = example.createCriteria();
				criteria.andEqualTo("parentId",sysOrganizationOld.getId());
				List<SysOrganization> sysOrganizations = organizationMapper.selectByExample(example);
				if (!sysOrganizations.isEmpty()) {
					for(SysOrganization sysOrganization:sysOrganizations){
						if(StringUtils.equals(sysOrganization.getId(),parentId)){
							sysOrganizationParent.setParentId(sysOrganizationOld.getParentId());
							organizationMapper.updateByPrimaryKeySelective(sysOrganizationParent);
						}else{
							recursiveCheckParentIsChildren(sysOrganizationOld.getParentId(),organization.getParentId(),sysOrganization,sysOrganizationParent);
						}
					}
				}
			}
		}
		if(selectCountByParentId(organization.getId())>0) {
			organization.setHasChildren(true);
		}else{
			organization.setHasChildren(false);
		}
		int count = organizationMapper.updateByPrimaryKeySelective(organization);
		if(count<=0){
			return count;
		}
		updateHasChildrennToParent(parentId);
		if(sysOrganizationOld!=null){
			updateHasChildrennToParent(sysOrganizationOld.getParentId());
		}
		return count;

	}

	@Override
	public int deleteOrganization(String id) {
        if (selectCountByParentId(id) > 0) {
            Example example = new Example(SysResource.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("parentId",id);
            List<SysOrganization> sysOrganizations = organizationMapper.selectByExample(example);
            if (!sysOrganizations.isEmpty()) {
                for(SysOrganization sysOrganization:sysOrganizations){
                    recursiveDelete( sysOrganization);
                }
            }
        }
        return delete(id);
	}

    /**
     * 递归删除
     * @param sysOrganization 机构
     */
    private void recursiveDelete(SysOrganization sysOrganization){

        if (selectCountByParentId(sysOrganization.getId()) > 0) {
            Example example = new Example(SysResource.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("parentId",sysOrganization.getId());
            List<SysOrganization> sysOrganizations = organizationMapper.selectByExample(example);
            if (!sysOrganizations.isEmpty()) {
                for(SysOrganization sysOrganizationChild:sysOrganizations){
                    recursiveDelete(sysOrganizationChild);
                }
            }
        }
        delete(sysOrganization.getId());
    }

    public int delete(String id) {
        SysOrganization sysOrganization = organizationMapper.selectByPrimaryKey(id);
        int count = organizationMapper.deleteByPrimaryKey(id);
        if(count<=0){
            return count;
        }
        updateHasChildrennToParent(sysOrganization!=null?sysOrganization.getParentId():null);

        Example exampleO = new Example(SysOrganizationResource.class);
        Example.Criteria criteriaO = exampleO.createCriteria();
        criteriaO.andEqualTo("organizationId", id);
        sysOrganizationResourceMapper.deleteByExample(exampleO);
        return count;
    }


	@Override
	public List<SysOrganizationResource> findOrganizationResources(String organizationId) {
		List<SysOrganizationResource> organizationResources;
		Example example = new Example(SysOrganizationResource.class);  
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("organizationId", organizationId);
		organizationResources = organizationResourceMapper.selectByExample(example);
		return organizationResources;
	}

	@Override
	public Result grantOrganizationResource(String ids,String organizationId) {
		Result customResult = new Result(200,"保存成功");

		int deleteCount;
		int saveCount = 0;
		
		String[] resourceIdArr = ids.split(",");
		List<SysOrganizationResource> organizationResources = new ArrayList<>();
		if(resourceIdArr.length>0 && !resourceIdArr[0].equals("")){
            for (String aResourceIdArr : resourceIdArr) {
                SysOrganizationResource organizationResource = new SysOrganizationResource();
                organizationResource.setId(CodeUtil.getTimeSequenceAsRandomCode());
                organizationResource.setOrganizationId(organizationId);
                organizationResource.setResourceId(aResourceIdArr);
                organizationResources.add(organizationResource);
            }
		}
		
		try {
			Example example = new Example(SysOrganizationResource.class);  
			Criteria criteria = example.createCriteria();
			criteria.andEqualTo("organizationId", organizationId);
			deleteCount = organizationResourceMapper.deleteByExample(example);
			if(organizationResources.size()>0){
				saveCount = organizationResourceMapper.insertOrganizationResourceByList(organizationResources);
			}
			customResult.setMessage("删除"+deleteCount+"条记录，保存"+saveCount+"条记录！");
		} catch (Exception e) {
			customResult=Result.build(500, "保存失败！");
			e.printStackTrace();
		}
		return customResult;
	}

	@Override
	public List<SysOrganization> findOrganizationByUserId(String userId) {
		List<SysOrganization> organizations = new ArrayList<>();
		try {
			organizations = organizationMapper.selectOrganizationByUserId(userId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return organizations;
	}
	
}
